package question

import (
	"data/config"
	"data/view/common"
	"data/view/user"
	"fmt"
	"net/http"
	"public/message"
	"public/myhttp"
	"public/mylog"
	"public/mysqldb"
	"public/tools"
	"strings"

	"github.com/360EntSecGroup-Skylar/excelize"

	"github.com/ant0ine/go-json-rest/rest"
)

/*
	添加题目
*/
func Add(w rest.ResponseWriter, r *rest.Request) {
	var req AddParam
	tools.GetRequestJsonObj(r, &req)

	//参数检测
	if !tools.CheckParam(req.Access_token, req.Type) {
		w.WriteJson(message.GetErrorMsg(message.ParameterInvalid, req))
		return
	}
	//验证token，并获取用户名
	username, _, bfind := user.GetUserFromToken(req.Access_token)
	if !bfind {
		w.WriteJson(message.GetErrorMsg(message.TokenFailure))
		return
	}
	var db mysqldb.MySqlDB
	defer db.OnDestoryDB()
	orm := db.OnGetDBOrm(config.GetDbUrl())

	quest_no := common.CreateUnique(common.RECRUIT_TOPIC + req.Type)
	var quest Question_tbl
	quest.Topic = common.RECRUIT_TOPIC
	quest.Bundle = common.QuestionTypeMap[req.Type]
	quest.Quest_no = quest_no
	quest.Operator = username
	quest.Difficulty = "普通"
	err := orm.Create(&quest).Error
	if err != nil {
		w.WriteJson(message.GetErrorMsg(message.UnknownError))
		return
	}
	var result Question_return
	result.Topic = quest.Topic
	result.Bundle = quest.Bundle
	result.Pid = quest.Pid
	result.Quest_no = quest.Quest_no
	result.Title = quest.Title
	result.Content = quest.Content
	result.Answer = []string{}
	result.Attach = quest.Attach
	result.Full_score = quest.Full_score
	result.Limit_time = quest.Limit_time
	result.Operator = quest.Operator
	result.Picture, result.Options = []string{}, []string{}

	//选项
	if req.Type == common.SCHOICE_TYPE || req.Type == common.MCHOICE_TYPE { //选择题
		result.Options = []string{"", "", ""}
	}
	if req.Type == common.CHECK_TYPE { //判断题
		result.Options = []string{"是", "否"}
	}
	result.Difficulty = "普通"
	msg := message.GetSuccessMsg(message.NormalMessageId)
	msg.Data = result
	w.WriteJson(msg)
}

/*
	编辑题目
*/
func Update(w rest.ResponseWriter, r *rest.Request) {
	var req UpdateParam
	tools.GetRequestJsonObj(r, &req)

	//参数检测
	if !tools.CheckParam(req.Access_token) {
		w.WriteJson(message.GetErrorMsg(message.ParameterInvalid, req))
		return
	}
	//参数检测
	if req.Quest_no == "" && req.Type == "" {
		w.WriteJson(message.GetErrorMsg(message.ParameterInvalid))
		return
	}
	//验证token，并获取用户名
	username, _, bfind := user.GetUserFromToken(req.Access_token)
	if !bfind {
		w.WriteJson(message.GetErrorMsg(message.TokenFailure))
		return
	}
	var db mysqldb.MySqlDB
	defer db.OnDestoryDB()
	orm := db.OnGetDBOrm(config.GetDbUrl())

	var tmp Question_tbl
	if len(req.Quest_no) > 0 {
		orm.Where("quest_no = ?", req.Quest_no).Find(&tmp)
		if tmp.Id == 0 {
			w.WriteJson(message.GetErrorMsg(message.NotFindError))
			return
		}
	}
	if tmp.Bundle == common.SCHOICE_TYPE_C || req.Type == common.SCHOICE_TYPE { //单选题
		if len(req.Answer) > 0 && len(req.Answer) != 1 {
			w.WriteJson(message.GetErrorMsg(message.ParameterInvalid, "单选题多个选项"))
			return
		}
	}
	quest_no := req.Quest_no
	if len(req.Quest_no) == 0 {
		quest_no = common.CreateUnique(common.RECRUIT_TOPIC + req.Type)
	}
	if len(req.Difficulty) == 0 {
		req.Difficulty = "普通"
	}
	var quest Question_tbl
	quest.Topic = common.RECRUIT_TOPIC
	if len(req.Type) > 0 {
		quest.Bundle = common.QuestionTypeMap[req.Type]
	}
	quest.Quest_no = quest_no
	quest.Operator = username

	if len(req.Picture) > 0 {
		quest.Picture = fmt.Sprintf("%s", req.Picture[0])
		for i := 1; i < len(req.Picture); i++ {
			quest.Picture += common.SPLIT + fmt.Sprintf("%s", req.Picture[i])
		}
	}

	if len(req.Options) > 0 {
		quest.Option = fmt.Sprintf("%s", req.Options[0])
		for i := 1; i < len(req.Options); i++ {
			quest.Option += common.SPLIT + fmt.Sprintf("%s", req.Options[i])
		}
	}
	quest.Pid = req.Pid
	quest.Title = req.Title
	quest.Content = req.Content
	if len(req.Answer) > 0 {
		quest.Answer = fmt.Sprintf("%s", req.Answer[0])
		for i := 1; i < len(req.Answer); i++ {
			quest.Answer += common.SPLIT + fmt.Sprintf("%s", req.Answer[i])
		}
	}
	quest.Attach = req.Attach
	quest.Full_score = req.Full_score
	quest.Limit_time = req.Limit_time
	quest.Operator = username
	quest.Is_vaild = req.Is_vaild
	quest.Difficulty = req.Difficulty
	quest.Analysis = req.Analysis

	var err error
	if len(req.Quest_no) > 0 { //update
		err = orm.Table("question_tbl").Where("quest_no = ?", req.Quest_no).Updates(&quest).Error
	} else { //add
		err = orm.Create(&quest).Error
	}
	if err != nil {
		w.WriteJson(message.GetErrorMsg(message.UnknownError))
		return
	}
	msg := message.GetSuccessMsg(message.NormalMessageId)
	msg.Data = quest_no
	w.WriteJson(msg)
}

/*
	获取题目类别
*/
func GetType(w rest.ResponseWriter, r *rest.Request) {
	var req SearchParam
	tools.GetRequestJsonObj(r, &req)

	//参数检测
	if !tools.CheckParam(req.Access_token) {
		w.WriteJson(message.GetErrorMsg(message.ParameterInvalid, req))
		return
	}
	//验证token，并获取用户名
	_, _, bfind := user.GetUserFromToken(req.Access_token)
	if !bfind {
		w.WriteJson(message.GetErrorMsg(message.TokenFailure))
		return
	}
	var db mysqldb.MySqlDB
	defer db.OnDestoryDB()
	orm := db.OnGetDBOrm(config.GetDbUrl())

	var qs []Quest_type
	var result []string
	orm.Table("Question_tbl").Group("pid").Scan(&qs)
	if len(qs) > 0 {
		for _, v := range qs {
			result = append(result, v.Pid)
		}
	}
	msg := message.GetSuccessMsg(message.NormalMessageId)
	msg.Data = result
	w.WriteJson(msg)
}

/*
	删除题目
*/
func Delete(w rest.ResponseWriter, r *rest.Request) {
	var req UpdateParam
	tools.GetRequestJsonObj(r, &req)

	//参数检测
	if !tools.CheckParam(req.Access_token, req.Quest_no) {
		w.WriteJson(message.GetErrorMsg(message.ParameterInvalid, req))
		return
	}
	//验证token，并获取用户名
	_, _, bfind := user.GetUserFromToken(req.Access_token)
	if !bfind {
		w.WriteJson(message.GetErrorMsg(message.TokenFailure))
		return
	}
	var db mysqldb.MySqlDB
	defer db.OnDestoryDB()
	orm := db.OnGetDBOrm(config.GetDbUrl())
	//判断是否引用
	var exam []Examination_tmp
	orm.Table("examination_tbl").Where("questions like ?", "%"+req.Quest_no+"%").Find(&exam)
	if len(exam) > 0 {
		w.WriteJson(message.GetErrorMsg(message.BlockingAcess, "试卷存在引用"))
		return
	}
	//删除
	err := orm.Table("question_tbl").Delete(Question_tbl{}, "quest_no = ?", req.Quest_no).Error
	if err != nil {
		w.WriteJson(message.GetErrorMsg(message.UnknownError))
		return
	}
	w.WriteJson(message.GetSuccessMsg())
}

/*
	搜索题目
*/
func Search(w rest.ResponseWriter, r *rest.Request) {
	var req SearchParam
	tools.GetRequestJsonObj(r, &req)

	//参数检测
	if !tools.CheckParam(req.Access_token) {
		w.WriteJson(message.GetErrorMsg(message.ParameterInvalid, req))
		return
	}
	//验证token，并获取用户名
	_, _, bfind := user.GetUserFromToken(req.Access_token)
	if !bfind {
		w.WriteJson(message.GetErrorMsg(message.TokenFailure))
		return
	}
	var db mysqldb.MySqlDB
	defer db.OnDestoryDB()
	orm := db.OnGetDBOrm(config.GetDbUrl())
	var tmp, tmp2 []Question_tbl
	var result []Question_return

	if req.Page_num == 0 {
		req.Page_num = 1
	}
	var contentCount int = 50 //每页50行数据
	var startCount int = (req.Page_num - 1) * contentCount

	sql := orm.Where("1 = 1").Offset(startCount).Limit(contentCount)
	sql2 := orm.Where("1 = 1")
	if req.Topic != "" {
		sql = sql.Where("topic = ?", req.Topic)
		sql2 = sql2.Where("topic = ?", req.Topic)
	}
	if req.Bundle != "" {
		sql = sql.Where("bundle = ?", req.Bundle)
		sql2 = sql2.Where("bundle = ?", req.Bundle)
	}
	if req.Pid != "" {
		sql = sql.Where("pid = ?", req.Pid)
		sql2 = sql2.Where("pid = ?", req.Pid)
	}
	if req.Quest_no != "" {
		sql = sql.Where("quest_no = ?", req.Quest_no)
		sql2 = sql2.Where("quest_no = ?", req.Quest_no)
	}
	if req.Title != "" {
		sql = sql.Where("title like ?", "%"+req.Title+"%")
		sql2 = sql2.Where("title like ?", "%"+req.Title+"%")
	}
	if req.Content != "" {
		sql = sql.Where("content like ?", "%"+req.Content+"%")
		sql2 = sql2.Where("content like ?", "%"+req.Content+"%")
	}
	if req.Difficulty != "" {
		sql = sql.Where("difficulty = ?", req.Difficulty)
		sql2 = sql2.Where("difficulty = ?", req.Difficulty)
	}
	sql.Find(&tmp)
	sql2.Find(&tmp2)
	if len(tmp) > 0 {
		for _, v := range tmp {
			var t Question_return
			t.Analysis = v.Analysis
			t.Answer = strings.Split(v.Answer, common.SPLIT)
			t.Attach = v.Attach
			t.Bundle = v.Bundle
			t.Content = v.Content
			t.Full_score = v.Full_score
			t.Is_vaild = v.Is_vaild
			t.Limit_time = v.Limit_time
			t.Operator = v.Operator
			t.Options = strings.Split(v.Option, common.SPLIT)
			t.Picture = strings.Split(v.Picture, common.SPLIT)
			t.Pid = v.Pid
			t.Quest_no = v.Quest_no
			t.Title = v.Title
			t.Topic = v.Topic
			t.Difficulty = v.Difficulty
			t.Bundle_t = common.QuestionTypeEnMap[v.Bundle]
			result = append(result, t)
		}
	}
	var total_page int = tools.GetTotalPageNum(50, len(tmp2)) //总页数
	mk := make(map[string]interface{})
	mk["total_page"] = total_page
	mk["total_count"] = len(tmp2)
	mk["current_page"] = req.Page_num
	mk["current_data"] = result
	msg := message.GetSuccessMsg(message.NormalMessageId)
	msg.Data = mk
	w.WriteJson(msg)
}

/*
	批量添加题目
*/
func MultiAdd(w http.ResponseWriter, r *http.Request) {
	if r.Method == "POST" {
		access_token := r.PostFormValue("access_token")
		paper_name := r.PostFormValue("name")    //试卷名称
		paper_type := r.PostFormValue("subject") //试卷类别
		//参数检测
		if !tools.CheckParam(access_token) {
			myhttp.WriteJson(w, message.GetErrorMsg(message.ParameterInvalid))
			return
		}
		//验证token，并获取用户名
		username, _, bfind := user.GetUserFromToken(access_token)
		if !bfind {
			myhttp.WriteJson(w, message.GetErrorMsg(message.TokenFailure))
			return
		}
		result, optionDirs := myhttp.UploadMoreFile(r, "")
		if !result {
			myhttp.WriteJson(w, message.GetErrorMsg(message.UnknownError))
			return
		}
		//读取Excel文件
		xlsx, err := excelize.OpenFile("." + optionDirs[0][len(config.Url_host):])
		if err != nil {
			mylog.Error(err)
			myhttp.WriteJson(w, message.GetErrorMsg(message.UnknownError))
			return
		}
		single_choice := xlsx.GetRows(common.SCHOICE_TYPE_C)
		multi_choice := xlsx.GetRows(common.MCHOICE_TYPE_C)
		check := xlsx.GetRows(common.CHECK_TYPE_C)
		fill := xlsx.GetRows(common.FILL_TYPE_C)
		brief := xlsx.GetRows(common.BRIEF_TYPE_C)

		b, rows_quest1 := readFromExcel(single_choice, username, common.SCHOICE_TYPE)
		b, rows_quest2 := readFromExcel(multi_choice, username, common.MCHOICE_TYPE)
		b, rows_quest3 := readFromExcel(check, username, common.CHECK_TYPE)
		b, rows_quest4 := readFromExcel(fill, username, common.FILL_TYPE)
		b, rows_quest5 := readFromExcel(brief, username, common.BRIEF_TYPE)

		//同时创建试卷
		if len(paper_name) > 0 && len(paper_type) > 0 {
			questions := make([]string, len(rows_quest1)+len(rows_quest2)+len(rows_quest3)+len(rows_quest4)+len(rows_quest5))
			copy(questions, rows_quest1)
			copy(questions[len(rows_quest1):], rows_quest2)
			copy(questions[len(rows_quest1)+len(rows_quest2):], rows_quest3)
			copy(questions[len(rows_quest1)+len(rows_quest2)+len(rows_quest3):], rows_quest4)
			copy(questions[len(rows_quest1)+len(rows_quest2)+len(rows_quest3)+len(rows_quest4):], rows_quest5)
			b = CreatePaperTmp(paper_name, paper_type, username, questions)
		}
		if !b {
			myhttp.WriteJson(w, message.GetErrorMsg(message.UnknownError))
			return
		}
		myhttp.WriteJson(w, message.GetSuccessMsg())
	} else {
		myhttp.WriteJson(w, message.MessageBody{State: false, Code: 405, Error: "method not allowed", Data: nil})

	}
	return
}
